package com.taxx.util;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 日期工具类
 * 
 * @author taxx
 * @since 2024-01-01
 */
@Slf4j
public class DateUtil {

    /**
     * 智能解析日期字符串为LocalDate
     * 支持多种常见格式，包括一位数的月份和日期
     * 
     * @param value 日期字符串
     * @return LocalDate对象，解析失败返回null
     */
    public static LocalDate parseDate(String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        
        String trimmedValue = value.trim();
        
        try {
            // 尝试多种标准日期格式
            String[] patterns = {
                "yyyy-MM-dd", "yyyy/MM/dd", "yyyy年MM月dd日",
                "yyyy-M-d", "yyyy/M/d", "yyyy年M月d日",      // 支持一位数月份和日期
                "yyyy-MM-d", "yyyy/MM/d", "yyyy年MM月d日",   // 支持一位数日期
                "yyyy-M-dd", "yyyy/M/dd", "yyyy年M月dd日"    // 支持一位数月份
            };
            
            for (String pattern : patterns) {
                try {
                    return LocalDate.parse(trimmedValue, DateTimeFormatter.ofPattern(pattern));
                } catch (Exception e) {
                    // 继续尝试下一个格式
                }
            }
            
            // 如果标准格式都失败，尝试智能解析
            LocalDate smartParsedDate = parseSmartDate(trimmedValue);
            if (smartParsedDate != null) {
                return smartParsedDate;
            }
            
            log.warn("无法解析日期值: '{}'", trimmedValue);
            return null;
            
        } catch (Exception e) {
            log.error("日期解析过程中发生异常，值: '{}'", trimmedValue, e);
            return null;
        }
    }
    
    /**
     * 智能日期解析，处理各种常见的日期格式
     * 
     * @param value 日期字符串
     * @return LocalDate对象，解析失败返回null
     */
    private static LocalDate parseSmartDate(String value) {
        try {
            // 处理 yyyy/M/d 格式（如 2022/9/23）
            if (value.matches("\\d{4}[/年]\\d{1,2}[/月]\\d{1,2}")) {
                String[] parts = value.replaceAll("[年月]", "/").split("/");
                if (parts.length == 3) {
                    int year = Integer.parseInt(parts[0]);
                    int month = Integer.parseInt(parts[1]);
                    int day = Integer.parseInt(parts[2]);
                    
                    if (isValidDate(year, month, day)) {
                        try {
                            return LocalDate.of(year, month, day);
                        } catch (Exception e) {
                            log.debug("智能解析日期验证失败: {}/{}/{}", year, month, day);
                        }
                    }
                }
            }
            
            // 处理 yyyy-M-d 格式（如 2022-9-23）
            if (value.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) {
                String[] parts = value.split("-");
                if (parts.length == 3) {
                    int year = Integer.parseInt(parts[0]);
                    int month = Integer.parseInt(parts[1]);
                    int day = Integer.parseInt(parts[2]);
                    
                    if (isValidDate(year, month, day)) {
                        try {
                            return LocalDate.of(year, month, day);
                        } catch (Exception e) {
                            log.debug("智能解析日期验证失败: {}-{}-{}", year, month, day);
                        }
                    }
                }
            }
            
            // 处理 yyyy年M月d日 格式（如 2022年9月23日）
            if (value.matches("\\d{4}年\\d{1,2}月\\d{1,2}日")) {
                String yearStr = value.substring(0, 4);
                String monthStr = value.substring(value.indexOf("年") + 1, value.indexOf("月"));
                String dayStr = value.substring(value.indexOf("月") + 1, value.indexOf("日"));
                
                int year = Integer.parseInt(yearStr);
                int month = Integer.parseInt(monthStr);
                int day = Integer.parseInt(dayStr);
                
                if (isValidDate(year, month, day)) {
                    try {
                        return LocalDate.of(year, month, day);
                    } catch (Exception e) {
                        log.debug("智能解析日期验证失败: {}年{}月{}日", year, month, day);
                    }
                }
            }
            
        } catch (Exception e) {
            log.debug("智能日期解析失败: {}", value, e);
        }
        
        return null;
    }
    
    /**
     * 验证日期是否有效
     * 
     * @param year 年份
     * @param month 月份
     * @param day 日期
     * @return 是否有效
     */
    private static boolean isValidDate(int year, int month, int day) {
        return month >= 1 && month <= 12 && day >= 1 && day <= 31;
    }
    
    /**
     * 解析日期时间字符串为LocalDateTime
     * 
     * @param value 日期时间字符串
     * @return LocalDateTime对象，解析失败返回null
     */
    public static LocalDateTime parseDateTime(String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        
        String trimmedValue = value.trim();
        
        try {
            // 尝试多种日期时间格式
            String[] patterns = {
                "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy年MM月dd日 HH:mm:ss",
                "yyyy-M-d H:m:s", "yyyy/M/d H:m:s", "yyyy年M月d日 H:m:s",      // 支持一位数
                "yyyy-MM-dd H:m:s", "yyyy/MM/dd H:m:s", "yyyy年MM月dd日 H:m:s", // 支持一位数时分秒
                "yyyy-M-dd HH:mm:ss", "yyyy/M/dd HH:mm:ss", "yyyy年M月dd日 HH:mm:ss" // 支持一位数月份
            };
            
            for (String pattern : patterns) {
                try {
                    return LocalDateTime.parse(trimmedValue, DateTimeFormatter.ofPattern(pattern));
                } catch (Exception e) {
                    // 继续尝试下一个格式
                }
            }
            
            // 如果标准格式都失败，尝试智能解析
            LocalDateTime smartParsedDateTime = parseSmartDateTime(trimmedValue);
            if (smartParsedDateTime != null) {
                return smartParsedDateTime;
            }
            
            log.warn("无法解析日期时间值: '{}'", trimmedValue);
            return null;
            
        } catch (Exception e) {
            log.error("日期时间解析过程中发生异常，值: '{}'", trimmedValue, e);
            return null;
        }
    }
    
    /**
     * 智能日期时间解析
     * 
     * @param value 日期时间字符串
     * @return LocalDateTime对象，解析失败返回null
     */
    private static LocalDateTime parseSmartDateTime(String value) {
        try {
            // 处理 yyyy/M/d H:m:s 格式
            if (value.matches("\\d{4}[/年]\\d{1,2}[/月]\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
                String[] dateTimeParts = value.replaceAll("[年月]", "/").split("\\s+");
                if (dateTimeParts.length == 2) {
                    String[] dateParts = dateTimeParts[0].split("/");
                    String[] timeParts = dateTimeParts[1].split(":");
                    
                    if (dateParts.length == 3 && timeParts.length == 3) {
                        int year = Integer.parseInt(dateParts[0]);
                        int month = Integer.parseInt(dateParts[1]);
                        int day = Integer.parseInt(dateParts[2]);
                        int hour = Integer.parseInt(timeParts[0]);
                        int minute = Integer.parseInt(timeParts[1]);
                        int second = Integer.parseInt(timeParts[2]);
                        
                        if (isValidDateTime(year, month, day, hour, minute, second)) {
                            try {
                                return LocalDateTime.of(year, month, day, hour, minute, second);
                            } catch (Exception e) {
                                log.debug("智能解析日期时间验证失败: {}/{}/{} {}:{}:{}", year, month, day, hour, minute, second);
                            }
                        }
                    }
                }
            }
            
            // 处理 yyyy-M-d H:m:s 格式
            if (value.matches("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}")) {
                String[] dateTimeParts = value.split("\\s+");
                if (dateTimeParts.length == 2) {
                    String[] dateParts = dateTimeParts[0].split("-");
                    String[] timeParts = dateTimeParts[1].split(":");
                    
                    if (dateParts.length == 3 && timeParts.length == 3) {
                        int year = Integer.parseInt(dateParts[0]);
                        int month = Integer.parseInt(dateParts[1]);
                        int day = Integer.parseInt(dateParts[2]);
                        int hour = Integer.parseInt(timeParts[0]);
                        int minute = Integer.parseInt(timeParts[1]);
                        int second = Integer.parseInt(timeParts[2]);
                        
                        if (isValidDateTime(year, month, day, hour, minute, second)) {
                            try {
                                return LocalDateTime.of(year, month, day, hour, minute, second);
                            } catch (Exception e) {
                                log.debug("智能解析日期时间验证失败: {}-{}-{} {}:{}:{}", year, month, day, hour, minute, second);
                            }
                        }
                    }
                }
            }
            
        } catch (Exception e) {
            log.debug("智能日期时间解析失败: {}", value, e);
        }
        
        return null;
    }
    
    /**
     * 验证日期时间是否有效
     * 
     * @param year 年份
     * @param month 月份
     * @param day 日期
     * @param hour 小时
     * @param minute 分钟
     * @param second 秒
     * @return 是否有效
     */
    private static boolean isValidDateTime(int year, int month, int day, int hour, int minute, int second) {
        return month >= 1 && month <= 12 && day >= 1 && day <= 31 && 
               hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59;
    }
    
    /**
     * 格式化LocalDate为字符串
     * 
     * @param date LocalDate对象
     * @param pattern 格式模式
     * @return 格式化后的字符串
     */
    public static String formatDate(LocalDate date, String pattern) {
        if (date == null) {
            return null;
        }
        try {
            return date.format(DateTimeFormatter.ofPattern(pattern));
        } catch (Exception e) {
            log.error("日期格式化失败: {}", date, e);
            return null;
        }
    }
    
    /**
     * 格式化LocalDateTime为字符串
     * 
     * @param dateTime LocalDateTime对象
     * @param pattern 格式模式
     * @return 格式化后的字符串
     */
    public static String formatDateTime(LocalDateTime dateTime, String pattern) {
        if (dateTime == null) {
            return null;
        }
        try {
            return dateTime.format(DateTimeFormatter.ofPattern(pattern));
        } catch (Exception e) {
            log.error("日期时间格式化失败: {}", dateTime, e);
            return null;
        }
    }
    
    /**
     * 获取当前日期
     * 
     * @return 当前日期
     */
    public static LocalDate today() {
        return LocalDate.now();
    }
    
    /**
     * 获取当前日期时间
     * 
     * @return 当前日期时间
     */
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }
}
